/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { JsonReader } from '../../../util/json-reader.js';

import { ValueEntry } from './task-input-value-entry.js';

export namespace TaskBuiltIn {
  export enum Execution {
    COMMAND = 'BUILTIN_TASK_COMMAND',
    TOOLCHAIN = 'BUILTIN_TASK_TOOLCHAIN',
    ENV = 'BUILTIN_TASK_ENV',
  }

  enum DataType {
    MAP = 'Map',
    VALUE_ENTRY = 'ValueEntry',
    REG_EXP = 'RegExp',
  }

  const receiverMap: Map<DataType, Function> = new Map();
  receiverMap.set(DataType.MAP, (jsonEntry: any) => {
    return new Map(jsonEntry.value);
  });
  receiverMap.set(DataType.VALUE_ENTRY, (jsonEntry: any) => {
    const entry = JsonReader.parseJsonText<any>(jsonEntry.value, undefined);
    if (!entry) {
      return undefined;
    }
    return new ValueEntry(entry._name, entry._value);
  });
  receiverMap.set(DataType.REG_EXP, (jsonEntry: any) => {
    return new RegExp(jsonEntry.value);
  });

  const replacerMap: Map<Function, Function> = new Map();
  replacerMap.set(Map, (value: any) => {
    return {
      dataType: DataType.MAP,
      value: Array.from(value.entries()),
    };
  });
  replacerMap.set(ValueEntry, (value: any) => {
    return {
      dataType: DataType.VALUE_ENTRY,
      value: JSON.stringify(value),
    };
  });
  replacerMap.set(RegExp, (value: any) => {
    return {
      dataType: DataType.REG_EXP,
      value: value.source,
    };
  });

  export const snapshotSerializationReplacer = (key: string, value: any) => {
    const typeSet = [Map, ValueEntry, RegExp];
    for (const type of typeSet) {
      if (value instanceof type && replacerMap.has(type)) {
        return replacerMap.get(type)!(value);
      }
    }
    return value;
  };

  export const snapshotSerializationReceiver = (key: string, jsonEntry: any) => {
    if (typeof jsonEntry !== 'object' || jsonEntry === null || !receiverMap.has(jsonEntry.dataType)) {
      return jsonEntry;
    }
    return receiverMap.get(jsonEntry.dataType)!(jsonEntry);
  };
}
